package cn.lili.modules.im.serviceimpl;

import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.modules.im.entity.dos.ImMessage;
import cn.lili.modules.im.entity.dos.ImTalk;
import cn.lili.modules.im.entity.dto.MessageQueryParams;
import cn.lili.modules.im.mapper.ImMessageMapper;
import cn.lili.modules.im.mapper.ImTalkMapper;
import cn.lili.modules.im.service.ImMessageService;
import cn.lili.mybatis.util.PageUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

/**
 * Im消息 业务实现
 *
 * @author Chopper
 */
@Service
@RequiredArgsConstructor
public class ImMessageServiceImpl extends ServiceImpl<ImMessageMapper, ImMessage> implements ImMessageService {

    @Autowired
    private final ImTalkMapper imTalkMapper;

    /**
     * 根据时间倒叙
     *
     * @param list 消息列表
     */
    private static void listSort(List<ImMessage> list) {
        list.sort((e1, e2) -> {
            try {
                if (e1.getCreateTime().before(e2.getCreateTime())) {
                    return -1;
                } else {
                    return 1;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return 0;
        });
    }

    @Override
    public void read(String talkId, String accessToken) {
        LambdaUpdateWrapper<ImMessage> updateWrapper = new LambdaUpdateWrapper<>();
        String userId = Objects.requireNonNull(UserContext.getAuthUser(accessToken)).getId();
        updateWrapper.eq(ImMessage::getTalkId, talkId);
        updateWrapper.eq(ImMessage::getToUser, userId);
        updateWrapper.set(ImMessage::getIsRead, true);
        this.update(updateWrapper);
    }

    @Override
    public List<ImMessage> unReadMessages(String accessToken) {
        String userId = Objects.requireNonNull(UserContext.getAuthUser(accessToken)).getId();
        LambdaQueryWrapper<ImMessage> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ImMessage::getToUser, userId);
        queryWrapper.eq(ImMessage::getIsRead, false);
        return this.list(queryWrapper);
    }

    @Override
    public List<ImMessage> historyMessage(String accessToken, String to) {
        String userId = Objects.requireNonNull(UserContext.getAuthUser(accessToken)).getId();
        LambdaQueryWrapper<ImMessage> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.and(i -> i.eq(ImMessage::getToUser, userId).and(j -> j.eq(ImMessage::getFromUser, to)));
        queryWrapper.or(i -> i.eq(ImMessage::getToUser, to).and(j -> j.eq(ImMessage::getFromUser, userId)));
        queryWrapper.orderByDesc(ImMessage::getCreateTime);
        return this.list(queryWrapper);
    }

    @Override
    public Boolean hasNewMessage(String accessToken) {
        String userId = Objects.requireNonNull(UserContext.getAuthUser(accessToken)).getId();
        LambdaQueryWrapper<ImMessage> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ImMessage::getIsRead, false);
        queryWrapper.eq(ImMessage::getToUser, userId);
        return !this.list(queryWrapper).isEmpty();

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<ImMessage> getList(MessageQueryParams messageQueryParams) {
        List<ImMessage> messageList = this.page(PageUtil.initPage(messageQueryParams), messageQueryParams.initQueryWrapper()).getRecords();
        listSort(messageList);
        readMessage(messageQueryParams);
        return messageList;
    }

    @Override
    public Long unreadMessageCount() {
        AuthUser currentUser = UserContext.getCurrentUser();
        if (currentUser == null) {
            throw new ServiceException(ResultCode.USER_NOT_LOGIN);
        }
        return this.count(new LambdaQueryWrapper<ImMessage>().eq(ImMessage::getToUser, currentUser.getId()).eq(ImMessage::getIsRead, false));
    }

    @Override
    public void cleanUnreadMessage() {
        AuthUser currentUser = UserContext.getCurrentUser();
        if (currentUser == null) {
            throw new ServiceException(ResultCode.USER_NOT_LOGIN);
        }
        this.update(new LambdaUpdateWrapper<ImMessage>().eq(ImMessage::getToUser, currentUser.getId()).set(ImMessage::getIsRead, true));
    }

    /**
     * 阅读消息
     *
     * @param messageQueryParams 获取消息接口参数
     */
    @Transactional(rollbackFor = Exception.class)
    public void readMessage(MessageQueryParams messageQueryParams) {
        //判断用户类型
        AuthUser authUser = Objects.requireNonNull(UserContext.getCurrentUser());

        ImTalk imTalk = imTalkMapper.selectById(messageQueryParams.getTalkId());
        if (imTalk != null) {
            LambdaUpdateWrapper<ImMessage> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(ImMessage::getTalkId, messageQueryParams.getTalkId());
            updateWrapper.eq(ImMessage::getToUser, authUser.getId());
            updateWrapper.set(ImMessage::getIsRead, true);
            this.update(updateWrapper);
        }
    }

}